package com.fyp.client.ptma;

import java.io.InputStream;
import java.net.URL;
import java.util.List;

import org.apache.http.HttpResponse;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.AsyncTaskLoader;
import android.support.v4.content.Loader;
import android.view.View;
import android.widget.ListView;

import com.fyp.client.ptma.adapters.CustomAdapterApplicationsList;
import com.fyp.client.ptma.model.Application;
import com.fyp.client.ptma.utils.Device;
import com.fyp.client.ptma.utils.Helper;
import com.fyp.client.ptma.utils.NetworkConnectivity;
import com.fyp.client.ptma.xml.ResponseXml;
import com.fyp.client.ptma.xml.XmlBuilder;

public class ApplicationListFragment extends ListFragment implements
		LoaderManager.LoaderCallbacks<List<Application>>
{

	private ApplicationClickListener appClickListener;
	private CustomAdapterApplicationsList mAdapter;

	public CustomAdapterApplicationsList getmAdapter()
	{
		return mAdapter;
	}

	public void setmAdapter(CustomAdapterApplicationsList mAdapter)
	{
		this.mAdapter = mAdapter;
	}

	public static interface ApplicationClickListener
	{
		public void onListItemClick(Application application);
	}

	@Override
	public void onAttach(Activity activity)
	{
		if (activity instanceof ApplicationClickListener)
		{
			appClickListener = (ApplicationClickListener) activity;

		}

		super.onAttach(activity);
	}

	@Override
	public void onActivityCreated(Bundle savedInstanceState)
	{
		super.onActivityCreated(savedInstanceState);

		if (!NetworkConnectivity.isConntectedToInternet(getActivity()))
		{
			setEmptyText(getString(R.string.noInternet));

			setListShownNoAnimation(true);
			return;
		}

		setEmptyText("No Data Here");
		// Create an empty adapter we will use to display the loaded data.
		mAdapter = new CustomAdapterApplicationsList(getActivity());
		setListAdapter(mAdapter);

		// Start out with a progress indicator.
		setListShown(false);

		// Prepare the loader. Either re-connect with an existing one,
		// or start a new one.
		getLoaderManager().initLoader(0, null, this);
	}

	@Override
	public void onListItemClick(ListView l, View v, int position, long id)
	{
		appClickListener.onListItemClick(mAdapter.getItem(position));
	}

	@Override
	public Loader<List<Application>> onCreateLoader(int arg0, Bundle arg1)
	{
		System.out.println("DataListFragment.onCreateLoader");
		return new DataListLoader(getActivity());
	}

	@Override
	public void onLoadFinished(Loader<List<Application>> arg0,
			List<Application> data)
	{
		mAdapter.setData(data);
		System.out.println("DataListFragment.onLoadFinished");
		// The list should now be shown.
		if (isResumed())
		{
			setListShown(true);
		} else
		{
			setListShownNoAnimation(true);
		}
	}

	@Override
	public void onLoaderReset(Loader<List<Application>> arg0)
	{
		mAdapter.setData(null);
	}

	private static class DataListLoader extends
			AsyncTaskLoader<List<Application>>
	{

		private List<Application> apps;
		private static final int INTERNET_CHECK = 0;
		private static final int NO_INTERNET = 1;
		private static final int CHECK_AUTHENTICITY = 2;
		private static final int GETTING_APPLICATIONS = 3;

		public DataListLoader(Context context)
		{
			super(context);
		}

		@Override
		public List<Application> loadInBackground()
		{
			ResponseXml wsResponse = null;
			if (!NetworkConnectivity.isConntectedToInternet(getContext()))
			{

				return null;
			}
			SharedPreferences pref = getContext().getSharedPreferences(
					Constants.SHARED_PREFERENCE, Context.MODE_PRIVATE);

			String myEmail = Helper.decrypt(pref.getString(
					Constants.PREF_KEY_MYEMAIL, null));
			String url = getContext().getString(R.string.WS_URL)
					+ getContext().getString(R.string.WS_APPLICATIONS);

			HttpResponse response = NetworkConnectivity.performPostOperation(
					url,
					XmlBuilder.getXmlForApplicatioList(myEmail,
							Device.getDeviceNumber(getContext())));
			try
			{
				wsResponse = Helper.getResponseObject(response);

				switch (wsResponse.getStatusCode())
				{
				case ResponseXml.NOT_LOGGEDIN:
					// publishProgress(ResponseXml.NOT_LOGGEDIN);
					// return ResponseXml.NOT_LOGGEDIN;
				case ResponseXml.NOT_REGISTERED:
					// publishProgress(ResponseXml.NOT_REGISTERED);
					// return ResponseXml.NOT_REGISTERED;

				case ResponseXml.OK:
					String url1 = getContext().getString(
							R.string.WS_RESOURCE_URL)
							+ "resources/images/dummyIcon.png";
					for (Application application : wsResponse.getResponseBody()
							.getApplications())
					{
						try
						{
							InputStream isBitmap = new URL(url1)
									.openConnection().getInputStream();
							Bitmap bitmap = BitmapFactory
									.decodeStream(isBitmap);

							application.setApplicationIcon(bitmap);
						} catch (Exception e)
						{
							e.printStackTrace();
						}

					}

				default:
					break;
				}

			} catch (Exception e)
			{
				e.printStackTrace();

			}

			return wsResponse.getResponseBody().getApplications();
		}

		/**
		 * Called when there is new data to deliver to the client. The super
		 * class will take care of delivering it; the implementation here just
		 * adds a little more logic.
		 */
		@Override
		public void deliverResult(List<Application> listOfData)
		{
			if (isReset())
			{
				// An async query came in while the loader is stopped. We
				// don't need the result.
				if (listOfData != null)
				{
					onReleaseResources(listOfData);
				}
			}
			List<Application> oldApps = apps;
			apps = listOfData;

			if (isStarted())
			{
				// If the Loader is currently started, we can immediately
				// deliver its results.
				super.deliverResult(listOfData);
			}

			// At this point we can release the resources associated with
			// 'oldApps' if needed; now that the new result is delivered we
			// know that it is no longer in use.
			if (oldApps != null)
			{
				onReleaseResources(oldApps);
			}
		}

		/**
		 * Handles a request to start the Loader.
		 */
		@Override
		protected void onStartLoading()
		{
			if (apps != null)
			{
				// If we currently have a result available, deliver it
				// immediately.
				deliverResult(apps);
			}

			if (takeContentChanged() || apps == null)
			{
				// If the data has changed since the last time it was loaded
				// or is not currently available, start a load.
				forceLoad();
			}
		}

		/**
		 * Handles a request to stop the Loader.
		 */
		@Override
		protected void onStopLoading()
		{
			// Attempt to cancel the current load task if possible.
			cancelLoad();
		}

		/**
		 * Handles a request to cancel a load.
		 */
		@Override
		public void onCanceled(List<Application> apps)
		{
			super.onCanceled(apps);

			// At this point we can release the resources associated with 'apps'
			// if needed.
			onReleaseResources(apps);
		}

		/**
		 * Handles a request to completely reset the Loader.
		 */
		@Override
		protected void onReset()
		{
			super.onReset();

			// Ensure the loader is stopped
			onStopLoading();

			// At this point we can release the resources associated with 'apps'
			// if needed.
			if (apps != null)
			{
				onReleaseResources(apps);
				apps = null;
			}
		}

		/**
		 * Helper function to take care of releasing resources associated with
		 * an actively loaded data set.
		 */
		protected void onReleaseResources(List<Application> apps)
		{
		}

	}

}
